package com.biz.aoao.mysql.mysqlbinlogsync.core;

import com.biz.aoao.mysql.mysqlbinlogsync.annotation.MysqlSyncListener;
import com.biz.aoao.mysql.mysqlbinlogsync.listener.IMysqlDataListener;
import lombok.Data;
import org.springframework.aop.support.AopUtils;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @Author scgaopan
 * @Date 2020/8/5 21:41
 * @Version 1.0
 * @Desc
 */
@Data
public class MysqlDataListenerData {

    private Long serverid;
    private String database;
    private String table;
    private Class<?> entityClass;
    private IMysqlDataListener listener;

    public MysqlDataListenerData(IMysqlDataListener listener){
        this.listener=listener;
        /*获取当前lister的真实class*/
        Class<?> targetClass = AopUtils.getTargetClass(listener);
        /*获取对就的Annotation对象*/
        MysqlSyncListener annotation = AnnotationUtils.getAnnotation(targetClass, MysqlSyncListener.class);
        if(annotation==null){
            throw  new RuntimeException("实现com.biz.aoao.mysql.mysqlbinlogsync.annotation.MysqlSyncListener 接口的类，必须加上MysqlSyncListener注解");
        }
        this.serverid=Long.valueOf(annotation.serverid());
        this.database=annotation.database();
        this.table=annotation.table();
        entityClass=getEntityClass(targetClass);
    }

    private Class<?> getEntityClass(Class<?> entityClass){
        if(entityClass==Object.class){
            return null;
        }
        /*获取当前类的所有实现接口*/
        Type[] types = entityClass.getGenericInterfaces();
        if (types.length == 0) {
            types = new Type[] {entityClass.getGenericSuperclass()};
        }
        for(Type type:types){
            //如果此类型有范型的定义
            if(type instanceof ParameterizedType){
                //获取对应的范型的对象
                Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments();
                return (Class<?>) actualTypeArguments[0];
            }
        }
        return getEntityClass(entityClass.getSuperclass());
    }
}
